using System;
using System.Collections.Generic;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.I18N;

namespace OracleInternal.TTC
{
	internal class TTCClob : TTCLob
	{
		internal bool m_bLittleEndianClob;

		internal TTCClob(MarshallingEngine mEngine)
			: base(mEngine)
		{
		}

		internal long Read(byte[] lobLocator, long locatorOffset, long numCharsToRead, bool bVariableWidthChar, out byte[] outBuffer)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCClob, OracleTraceFuncName.Read);
			}
			try
			{
				outBuffer = null;
				byte[] array = null;
				Initialize();
				array = ((!m_variableWidthChar) ? new byte[(int)numCharsToRead * 3] : new byte[(int)numCharsToRead * 2]);
				m_lobOperation = 2L;
				m_sourceLobLocator = lobLocator;
				m_sourceOffset = locatorOffset;
				m_lobAmount = numCharsToRead;
				m_bSendLobAmount = true;
				m_outBuffer = array;
				WriteFunctionHeader();
				WriteLobOperation();
				m_marshallingEngine.m_oraBufWriter.FlushData();
				ReceiveResponse();
				outBuffer = array;
				return m_lobBytesRead;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCClob, OracleTraceFuncName.Read, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCClob, OracleTraceFuncName.Read);
				}
			}
		}

		internal void Read(byte[] lobLocator, long locatorOffset, long numCharsToRead, List<ArraySegment<byte>> dataSegments)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCClob, OracleTraceFuncName.Read);
			}
			try
			{
				Initialize();
				m_lobOperation = 2L;
				m_sourceLobLocator = lobLocator;
				m_sourceOffset = locatorOffset;
				m_lobAmount = numCharsToRead;
				m_bSendLobAmount = true;
				WriteFunctionHeader();
				WriteLobOperation();
				m_marshallingEngine.m_oraBufWriter.FlushData();
				ReceiveResponse(dataSegments);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCClob, OracleTraceFuncName.Read, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCClob, OracleTraceFuncName.Read);
				}
			}
		}

		internal long Write(byte[] lobLocator, bool bIsNClob, short serverNCharSet, long locatorOffset, char[] inBuffer, long inBufferOffset, long numCharsToWrite)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCClob, OracleTraceFuncName.Write);
			}
			try
			{
				if (TTCLob.IsReadOnly(lobLocator))
				{
					throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
				}
				if (TTCLob.IsQuasiOrTempVBL(lobLocator))
				{
					throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
				}
				bool flag = false;
				if ((lobLocator[6] & 0x80) == 128)
				{
					flag = true;
				}
				if ((lobLocator[7] & 0x40) == 64)
				{
					m_bLittleEndianClob = true;
				}
				byte[] array = null;
				if (!flag)
				{
					array = (bIsNClob ? m_marshallingEngine.m_nCharSetConv.ConvertCharsToBytes(inBuffer, (int)inBufferOffset, (int)numCharsToWrite) : m_marshallingEngine.m_dbCharSetConv.ConvertCharsToBytes(inBuffer, (int)inBufferOffset, (int)numCharsToWrite));
				}
				else
				{
					array = new byte[(int)numCharsToWrite * 2];
					array = ((m_marshallingEngine.DBVersion >= 10200 || !m_bLittleEndianClob) ? Conv.GetInstance(2000).ConvertCharsToBytes(inBuffer, (int)inBufferOffset, (int)numCharsToWrite) : Conv.GetInstance(2002).ConvertCharsToBytes(inBuffer, (int)inBufferOffset, (int)numCharsToWrite));
				}
				Initialize();
				m_lobOperation = 64L;
				m_sourceLobLocator = lobLocator;
				m_sourceOffset = locatorOffset;
				m_lobAmount = numCharsToWrite;
				m_bSendLobAmount = true;
				m_inBuffer = array;
				WriteFunctionHeader();
				WriteLobOperation();
				if (flag)
				{
					m_lobData.WriteLobData(m_inBuffer, 0L, m_inBuffer.Length);
				}
				else
				{
					m_lobData.WriteLobData(m_inBuffer, 0L, m_inBuffer.Length);
				}
				m_marshallingEngine.m_oraBufWriter.FlushData();
				ReceiveResponse();
				return m_lobAmount;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCClob, OracleTraceFuncName.Write, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCClob, OracleTraceFuncName.Write);
				}
			}
		}

		internal long Write(byte[] lobLocator, bool bIsNClob, short serverNCharSet, long locatorOffset, byte[] inBuffer, long inBufferOffset, long numCharsToWrite, bool bVariableWidthChar)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCClob, OracleTraceFuncName.Write);
			}
			try
			{
				if (TTCLob.IsReadOnly(lobLocator))
				{
					throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
				}
				if (TTCLob.IsQuasiOrTempVBL(lobLocator))
				{
					throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
				}
				if ((lobLocator[7] & 0x40) == 64)
				{
					m_bLittleEndianClob = true;
				}
				Initialize();
				m_lobOperation = 64L;
				m_sourceLobLocator = lobLocator;
				m_sourceOffset = locatorOffset;
				m_lobAmount = numCharsToWrite;
				m_bSendLobAmount = true;
				m_inBuffer = inBuffer;
				WriteFunctionHeader();
				WriteLobOperation();
				if (bVariableWidthChar)
				{
					m_lobData.WriteLobData(m_inBuffer, 0L, m_inBuffer.Length);
				}
				else
				{
					m_lobData.WriteLobData(m_inBuffer, 0L, m_inBuffer.Length);
				}
				m_marshallingEngine.m_oraBufWriter.FlushData();
				ReceiveResponse();
				return m_lobAmount;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCClob, OracleTraceFuncName.Write, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCClob, OracleTraceFuncName.Write);
				}
			}
		}

		internal override byte[] CreateTemporaryLob(bool bCache, bool bNClob, int duration)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCClob, OracleTraceFuncName.CreateTemporaryLob);
			}
			try
			{
				if (12 == duration)
				{
					throw new Exception("Invalid duration in CreateTemporaryLob");
				}
				Initialize();
				m_lobOperation = 272L;
				m_sourceLobLocator = new byte[40];
				m_sourceLobLocator[1] = 84;
				m_lobAmount = 10L;
				m_bSendLobAmount = true;
				if (bNClob)
				{
					m_sourceOffset = 2L;
				}
				else
				{
					m_sourceOffset = 1L;
				}
				m_destinationOffset = 112L;
				m_destinationLength = duration;
				m_bNullO2U = true;
				m_characterSet = (short)(bNClob ? 2000 : 178);
				m_lobSCN = new int[1];
				m_lobSCN[0] = (bCache ? 1 : 0);
				m_lobSCNLength = 1;
				WriteFunctionHeader();
				WriteLobOperation();
				m_marshallingEngine.m_oraBufWriter.FlushData();
				ReceiveResponse();
				return m_sourceLobLocator;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCClob, OracleTraceFuncName.CreateTemporaryLob, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCClob, OracleTraceFuncName.CreateTemporaryLob);
				}
			}
		}

		internal bool Open(byte[] lobLocator, int mode)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCClob, OracleTraceFuncName.Open);
			}
			try
			{
				int mode2 = 2;
				if (mode == 0)
				{
					mode2 = 1;
				}
				return OpenLob(lobLocator, mode2, 32768);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCClob, OracleTraceFuncName.Open, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCClob, OracleTraceFuncName.Open);
				}
			}
		}

		internal bool Close(byte[] lobLocator)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCClob, OracleTraceFuncName.Close);
			}
			try
			{
				return CloseLob(lobLocator, 65536);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCClob, OracleTraceFuncName.Close, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCClob, OracleTraceFuncName.Close);
				}
			}
		}
	}
}
